package com.yonyou.pmclouds.workconnect.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.annotation.Lock;
import com.yonyou.pmclouds.basecom.bp.processor.*;
import com.yonyou.pmclouds.basecom.bp.template.SingleDeleteBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.basecom.util.CommonFieldConst;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.project.processor.ProjectBillUpdateForUpdate;
import com.yonyou.pmclouds.project.processor.UpdateBillCountForInsertProcessor;
import com.yonyou.pmclouds.task.rmiitf.TaskRemoteService;
import com.yonyou.pmclouds.workConnect.entity.WorkConBillStatus;
import com.yonyou.pmclouds.workConnect.entity.WorkConReceiverVO;
import com.yonyou.pmclouds.workConnect.entity.WorkConnectVO;
import com.yonyou.pmclouds.workConnect.service.rmiitf.WorkConReceiverMaintain;
import com.yonyou.pmclouds.workConnect.service.rmiitf.WorkConReceiverQuery;
import com.yonyou.pmclouds.workConnect.service.rmiitf.WorkConnectMaintain;
import com.yonyou.pmclouds.workconnect.mapper.WorkConnectMapper;
import com.yonyou.pmclouds.workconnect.process.WorkConnectBeforeAddProcess;
import com.yonyou.pmclouds.workconnect.process.WorkConnectProjectLogPostProcess;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 工作联系service
 */
@Service(version = ApplicationConsts.APPLICATION_VERSION,interfaceClass=WorkConnectMaintain.class)
public class WorkConnectMaintainImpl implements WorkConnectMaintain{
	/**
	 * 需要更新的字段
	 */
	private static String[] UPDATE_FIELDS ={CommonFieldConst.MODIFIER, CommonFieldConst.MODIFYTIME,
			WorkConnectVO.TITLE,WorkConnectVO.CONTENT,CommonFieldConst.PKPROJECTPART};
	private static String[] UPDATE_BILLSTATUS = {WorkConnectVO.BILLSTATUS};
	@Autowired
	private WorkConnectMapper workConnectMapper;
    @Autowired
    private WorkConReceiverMaintain receiverMaintain;
	@Autowired
    private WorkConReceiverQuery receiverQuery;
    @Autowired
    private PictureRemoteService pictureService;
	@Autowired
	private MobileTaskInsertProcessor<WorkConnectVO> mobileTaskInsertProcessor;
	@Autowired
	private MobileTaskFinishProcessor<WorkConnectVO> mobileTaskFinishProcessor;
	@Autowired
	private UpdateBillCountForInsertProcessor.UpdateBillCountForInsertProcessorFactory<WorkConnectVO> billCountFactory;
    @Autowired
    private TaskRemoteService taskRemoteService;
    @Autowired
    private ProjectStatusCheckProcessor<WorkConnectVO> projectStatusCheckProcessor;
    @Autowired
    private ProjectBillUpdateForUpdate.ProjectBillForUpdateProcessorFactory<WorkConnectVO> billForUpdateProcessorFactory;
    @Autowired
    private WorkConnectProjectLogPostProcess workConnectProjectLogPostProcess;
    @Autowired
    private DocCenterProcessor docCenterProcessor;


    /**
     * 添加工作联系
     * @param workConnectVO
     * @return
     * @throws BusinessException
     */
    @Transactional
    @Override
    public WorkConnectVO addWorkConnect(WorkConnectVO workConnectVO) throws BusinessException {
        //设置租户信息
        workConnectVO.setPk_tenant(RuntimeEnvironment.getTenantId());
        // 插入主表
        SingleInsertBpTemplate<WorkConnectVO> bp = new SingleInsertBpTemplate<WorkConnectVO>(workConnectMapper);
        //工作联系必填字段校验
        bp.addBeforeProcessor(new WorkConnectBeforeAddProcess());
        // 更新审计信息
        bp.addBeforeProcessor(new AuditInfoInsertProcessor<WorkConnectVO>());
        //检查项目状态
        bp.addBeforeProcessor(projectStatusCheckProcessor);
        //插入移动代办
        bp.addAfterProcessor(mobileTaskInsertProcessor);
        //更新项目统计
        bp.addAfterProcessor(billCountFactory.getProcessor(BillTypeConst.WORKCONNECT_BILLTYPE));
        //智能日志
        bp.addAfterProcessor(workConnectProjectLogPostProcess);

        //插入主表
        workConnectVO = bp.insert(workConnectVO);
        // 插入图片数据
        pictureService.insertPictureForPub(workConnectVO, null);
        if (saveReceivers(workConnectVO)) return null;
        return workConnectVO;
    }


    /**
     * 删除工作联系
     * @param pk_WorkConnect
     * @return
     * @throws BusinessException
     */
    @Override
	public String deleteWorkConnect(String pk_WorkConnect) throws BusinessException {
	    WorkConnectVO tempVO = new WorkConnectVO();
	    tempVO.setPk_workconnect(pk_WorkConnect);
        SingleDeleteBpTemplate<WorkConnectVO> bp = new SingleDeleteBpTemplate<>(workConnectMapper);
	    bp.addBeforeProcessor(new AuditInfoUpdateProcessor<WorkConnectVO>());
		bp.delete(tempVO);
		return pk_WorkConnect;
	}

    /**
     * 更新工作联系
     * @param workConnectVO
     * @return
     * @throws BusinessException
     */
	@Override
	@Lock
	public WorkConnectVO updateWrokConnect(WorkConnectVO workConnectVO) throws BusinessException {
        SingleUpdateBpTemplate<WorkConnectVO> bp = new SingleUpdateBpTemplate<>(workConnectMapper, UPDATE_FIELDS);
		bp.addAfterProcessor(new AuditInfoUpdateProcessor<WorkConnectVO>());
		return bp.update(workConnectVO);
	}

    /**
     * 更新单据状态
     * @param pk_workconnect
     * @param receiverVO
     * @return
     * @throws BusinessException
     */
    @Override
    @Lock
    public WorkConnectVO updateBillStatus(String pk_workconnect, WorkConReceiverVO receiverVO) throws BusinessException {
        if(StringUtils.isEmpty(pk_workconnect)) {
            throw new BusinessException("接收单据为空,请检查!");
        }
        //获取接收信息
        WorkConnectVO vo = workConnectMapper.getById(pk_workconnect);
        // 旧数据处理：receiverVO如果为空的话，就是旧数据，只能有一个接收人
        if (receiverVO == null) {
            return dealOldData(vo);
        }
        //更新联系人信息，并给制单人发送消息
        receiverVO = receiverMaintain.update(receiverVO);
        //代办任务完成
        String pkReceiver   = receiverVO.getPkReceiver();
        taskRemoteService.finishTask(pk_workconnect, pkReceiver, WorkConReceiverVO.RECEIVE_STATUS_UNACCEPT);
        //根据工作联系查询接收人
        WorkConReceiverVO[] recVOs = receiverQuery.queryByWorkConnect(pk_workconnect);
        vo.setWorkConReceiverVOS(recVOs);
        //如果没有未接收的人员 更新工作联系的接收状态
        if (CollectionUtils.isEmpty(Arrays.stream(recVOs).filter(recvo -> recvo.getReceiveStatus() == 1).collect(Collectors.toList()))) {
            vo = updateStatusWorkConnect(pk_workconnect, vo, recVOs);
        }
        return vo;
    }

    /**
     * 处理历史单个接收人的问题 单表
     * @param vo
     * @return
     * @throws BusinessException
     */
    private WorkConnectVO dealOldData(WorkConnectVO vo) throws BusinessException {
        vo.setBillstatus(WorkConBillStatus.STATUS_ACCEPTED);
        SingleUpdateBpTemplate<WorkConnectVO> bp = new SingleUpdateBpTemplate<>(workConnectMapper, UPDATE_BILLSTATUS);
        bp.addAfterProcessor(billForUpdateProcessorFactory.getProcessor(BillTypeConst.WORKCONNECT_BILLTYPE));
        WorkConnectVO updatedVO = bp.update(vo);
        taskRemoteService.finishTask(updatedVO.getPk_workconnect(), updatedVO.getPkReceiver(), updatedVO.getBillstatus());
        return updatedVO;
    }

    /**
     * 更新工作联系的接收状态
     * @param pk_workconnect
     * @param vo
     * @param recVOs
     * @return
     * @throws BusinessException
     */
    private WorkConnectVO updateStatusWorkConnect(String pk_workconnect, WorkConnectVO vo, WorkConReceiverVO[] recVOs) throws BusinessException {
        String pkReceiver;
        vo.setBillstatus(WorkConBillStatus.STATUS_ACCEPTED);
        SingleUpdateBpTemplate<WorkConnectVO> bp = new SingleUpdateBpTemplate<>(workConnectMapper, UPDATE_BILLSTATUS);
        bp.addAfterProcessor(billForUpdateProcessorFactory.getProcessor(BillTypeConst.WORKCONNECT_BILLTYPE));
        bp.addAfterProcessor(docCenterProcessor);
        vo = bp.update(vo);
        for (WorkConReceiverVO recVO : recVOs) {
            pkReceiver = recVO.getPkReceiver();
            taskRemoteService.updateBillStatus(pk_workconnect, pkReceiver, WorkConReceiverVO.RECEIVE_STATUS_ACCEPTED);
        }
        return vo;
    }

    /**
     * 保存接收人信息
     * @param workConnectVO
     * @return
     * @throws BusinessException
     */
    private boolean saveReceivers(WorkConnectVO workConnectVO) throws BusinessException {
        // 获取多个接收人
        String[] pkReceivers = workConnectVO.getPkReceivers();
        String pkWorkConnect = workConnectVO.getPk_workconnect();
        if (ArrayUtils.isEmpty(pkReceivers) || StringUtils.isEmpty(pkWorkConnect)) {
            return true;
        }
        // 插入子表
        List<WorkConReceiverVO> receiverList = new ArrayList<>(pkReceivers.length);
        for (String pkReceiver : pkReceivers ) {
            WorkConReceiverVO vo = new WorkConReceiverVO();
            vo.setPkReceiver(pkReceiver);
            vo.setPkWorkconnect(pkWorkConnect);
            vo.setReceiveStatus(WorkConReceiverVO.RECEIVE_STATUS_UNACCEPT);
            receiverList.add(vo);
        }
        receiverMaintain.addVOs(receiverList.toArray(new WorkConReceiverVO[0]));
        return false;
    }

}
